﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace WhomaShuriken.Core.Utility{

    /// <summary>
    /// 暗号化処理
    /// </summary>
    public sealed class Crypt{
        
        /// <summary>
        /// シングルトン
        /// </summary>
        private static readonly Crypt crypt = new Crypt();

        /// <summary>
        /// 鍵
        /// </summary>
        private static byte[] key;

        /// <summary>
        /// 乱数
        /// </summary>
        private static byte[] iv;

        /// <summary>
        /// インスタンスコンストラクタ
        /// </summary>
        static Crypt(){
        
            Initalize();
        }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        private Crypt(){
        
        }

        /// <summary>
        /// 暗号化処理インスタンスを取得する
        /// </summary>
        /// <returns>
        /// 暗号化処理インスタンス
        /// </returns>
        public static Crypt GetInstance(){
        
            return crypt;
        }

        /// <summary>
        /// 初期化処理
        /// </summary>
        private static void Initalize(){
        
            string password = "password";
            RijndaelManaged rijndaelManaged = new RijndaelManaged();
            key = new byte[32];
            iv = new byte[16];
            int len = password.Length;
            for (int i = 0; i < 32; i++) 
                key[i] = (byte)password[i % len];
            for (int i = 0; i < 16; i++) 
                iv[i] = (byte)password[i % len];

        }

        /// <summary>
        /// 文字列を暗号化する
        /// </summary>
        /// <param name="value">
        /// 暗号化する文字列
        /// </param>
        /// <returns>
        /// 暗号化された文字列
        /// </returns>
        public string Encrypt(string value){
        
            try {

                byte[] bytes = Encoding.Unicode.GetBytes(value);
                RijndaelManaged rijndaelManaged = new RijndaelManaged();
                byte[] dest;
                MemoryStream memory = new MemoryStream();
                CryptoStream crypto = new CryptoStream(memory, rijndaelManaged.CreateEncryptor(key, iv), CryptoStreamMode.Write);
                crypto.Write(bytes, 0, bytes.Length);
                crypto.FlushFinalBlock();
                dest = memory.ToArray();
                return Convert.ToBase64String(dest);
            }catch{

                return "-";
            }
        }

        /// <summary>
        /// 文字列を復号化する
        /// </summary>
        /// <param name="value">
        /// 復号化する文字列
        /// </param>
        /// <returns>
        /// 復号化された文字列
        /// </returns>
        public string Decrypt(string value){
        
            try {

                byte [] bytes = Convert.FromBase64String(value);
                RijndaelManaged rijndaelManaged = new RijndaelManaged();
                byte[] dest;
                MemoryStream memory = new MemoryStream();
                CryptoStream crypto = new CryptoStream(memory, rijndaelManaged.CreateDecryptor(key, iv), CryptoStreamMode.Write);
                crypto.Write(bytes, 0, bytes.Length);
                crypto.FlushFinalBlock();
                dest = memory.ToArray();
                return Encoding.Unicode.GetString(dest);
            } catch {

                return "-";
            }
        }
    }
}
